package com.itzhanghada.rebitmq.compensation;

import com.itzhanghada.rebitmq.domin.vo.TransactionRecord;
import com.itzhanghada.rebitmq.enums.TransactionStatus;
import com.itzhanghada.rebitmq.mq.MessageSender;
import com.itzhanghada.rebitmq.redis.RedisStorageService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;

import java.util.Set;

@Component
public class CompensationService {
    private static final Logger logger = LoggerFactory.getLogger(CompensationService.class);
    
    @Autowired
    private RedisStorageService storageService;
    
    @Autowired
    private MessageSender messageSender;
    
    @Scheduled(fixedDelayString = "${rebit.mq.compensation.interval:30000}")
    public void compensate() {
        try {
            logger.info("Starting transaction compensation");
            
            // 获取需要补偿的事务ID（30秒未确认）
            Set<String> txIds = storageService.getCompensationTxIds(30000);
            
            if (txIds == null || txIds.isEmpty()) {
                logger.debug("No transactions need compensation");
                return;
            }
            
            logger.info("Found {} transactions need compensation", txIds.size());
            
            for (String txId : txIds) {
                compensateTransaction(txId);
            }
        } catch (Exception e) {
            logger.error("Error in compensation process", e);
        }
    }
    
    private void compensateTransaction(String txId) {
        try {
            TransactionRecord record = storageService.getTransactionRecord(txId);
            if (record == null) {
                logger.warn("Transaction record not found, txId: {}", txId);
                return;
            }
            
            // 检查重试次数
            if (record.getRetryCount() >= record.getMaxRetry()) {
                logger.warn("Transaction exceeded max retry count, txId: {}", txId);
                storageService.updateTransactionStatus(txId, TransactionStatus.FAILED);
                // 发送告警
                sendAlert(record);
                return;
            }
            
            // 根据状态进行不同的补偿处理
            switch (record.getStatus()) {
                case COMMITTED:
                    // 已提交但未发送，重新发送消息
                    messageSender.sendMessage(record);
                    break;
                    
                case SENT:
                    // 已发送但未消费，检查是否需要重新发送
                    checkAndResendIfNeeded(record);
                    break;
                    
                case RETRYING:
                    // 重试中，重新发送消息
                    messageSender.sendMessage(record);
                    break;
                    
                default:
                    logger.debug("Transaction status does not need compensation, txId: {}, status: {}", 
                                txId, record.getStatus());
                    break;
            }
        } catch (Exception e) {
            logger.error("Failed to compensate transaction, txId: {}", txId, e);
        }
    }
    
    private void checkAndResendIfNeeded(TransactionRecord record) {
        // 这里可以添加更复杂的检查逻辑
        // 例如：检查消息是否真的没有被消费
        
        // 简单实现：超过一定时间未消费就重新发送
        long sentTime = record.getUpdateTime();
        long currentTime = System.currentTimeMillis();
        
        if (currentTime - sentTime > 60000) { // 60秒未消费
            logger.info("Message seems not consumed, resending, txId: {}", record.getTxId());
            messageSender.sendMessage(record);
        }
    }
    
    private void sendAlert(TransactionRecord record) {
        // 实现告警逻辑，可以发送邮件、短信或调用告警接口
        logger.error("ALERT: Transaction failed after max retries, txId: {}, service: {}, method: {}", 
                    record.getTxId(), record.getServiceName(), record.getMethodName());
    }
}